#!/usr/bin/python
# -*- coding: utf-8 -*-

import re
import urllib
from ..Util import Download,JapaneseConsole


def thumb(url):
    i=url.rindex("/")
    return url[:i]+"/s72"+url[i:]


class SyncRSS:
    def _parseRSS(self):
        raise NotImplementedError("parseRSS")
    def _isCreated(self):
        raise NotImplementedError("isCreated")
    
    def _downloadRSS(self):
        if not hasattr(self,"_rss"):
            self._rss=Download(self._url)
        
    def Sync(self):
        if not self._isCreated():
            self._downloadRSS()
            self._parseRSS()
        return self

class Photo:
    def __init__(self,user_id,album_id,photo_id,title,url,timestamp,width,height,checksum,exifInfos,keywords,location=None):
        params=locals()
        params.pop("self")
        for paramName,paramVal in params.iteritems():
            setattr(self,paramName,paramVal)
    def __str__(self):
        return "Photo[ID:%s/%d/%d]=\n\ttitle:%s,\turl:%s\ttimestamp:%d\n\tsize={%dx%d}\tchecksum=%s" % (
            self.user_id,self.album_id,self.photo_id
            ,self.title,self.url,self.timestamp
            ,self.width,self.height,self.checksum
        )
        
#RSSのパースだけを実装したクラス。URLはセットされてない！注意。
#リファレンスはここ
#http://code.google.com/intl/ja-JP/apis/gdata/docs/2.0/reference.html#Queries
class PhotoCollection(SyncRSS):
    def _parseRSS(self):
        if not hasattr(self,"_geoOnly"): self._geoOnly=False

        mTotal=re.compile('<openSearch:totalResults>([^<]+)').search(self._rss)
        self.TotalCount=-1 if mTotal is None else mTotal.group(1)
        
        mTitle=re.compile('<title>([^<]+)').search(self._rss)
        self.Title="" if mTitle is None else mTitle.group(1)
                
        self.Photos=list()
        for mItem in re.compile('<item>(.*?)</item>',re.M|re.S).finditer(self._rss):
            item=mItem.group(1)
            if self._geoOnly and  not "<gml:pos>" in item: continue
            
            m=re.compile('<author>([^<]+) \(([^)]+)').search(item)
            author={"id":""} if m is None else {"id":m.group(1),"name":m.group(2)}
            
            m=re.compile('<gphoto:albumid>([^<]+)').search(item)
            album_id=-1 if m is None else int(m.group(1))
            
            m=re.compile('<gphoto:id>([^<]+)').search(item)
            photo_id=-1 if m is None else int(m.group(1))
            
            m=re.compile('<title>([^<]+)').search(item)
            title="" if m is None else m.group(1)
            
            m=re.compile("<media:content url='([^']+)").search(item)
            photo_url="" if m is None else m.group(1)
            
            m=re.compile('<gphoto:timestamp>([^<]+)').search(item)
            timestamp=-1 if m is None else int(m.group(1))
            
            m=re.compile('<gphoto:width>([^<]+)').search(item)
            width=-1 if m is None else int(m.group(1))
            m=re.compile('<gphoto:height>([^<]+)').search(item)
            height=-1 if m is None else int(m.group(1))
       
            m=re.compile('<gphoto:checksum>([^<]+)').search(item)
            checksum="" if m is None else m.group(1)
            
            exifInfos=dict()
            reExif=re.compile('<exif:([^>]+)>([^<]+)')
            mExifs=re.compile('<exif:tags>(.*?)</exif:tags>',re.M|re.S).search(item)
            if not mExifs is None:
                for mExif in reExif.finditer(mExifs.group(1)):
                    exifInfos[mExif.group(1)]=mExif.group(2)

            m=re.compile('<media:keywords>([^<]+)').search(item)
            keywords="" if m is None else m.group(1)
            
            m=re.compile('<gml:pos>([^<]+)').search(item)
            location=None if m is None else m.group(1).split(" ")
            
            self.Photos.append(Photo(author["id"],album_id,photo_id,title,photo_url,timestamp,width,height,checksum,exifInfos,keywords,location))           

    def _isCreated(self):
        return hasattr(self,"Photos")

class Album(PhotoCollection):
    def __init__(self,user_id,album_id,geoOnly=True,autoSync=True):
        self.user_id=user_id
        self.album_id=album_id
        self._geoOnly=geoOnly
        self._url="http://picasaweb.google.com/data/feed/api/user/%s/albumid/%s?alt=rss" %(user_id,album_id)
        if autoSync:
            self.Sync()

class SearchResult(PhotoCollection):
    def __init__(self,unicodedQuery,rpp=500,page=0,geoOnly=True,unicodedLocation=None):
        url="http://picasaweb.google.com/data/feed/api/all"
        q={"alt":"rss","kind":"photo","access":"public","filter":"1","q":unicodedQuery.encode("utf-8"),"max-results":rpp,"start-index":str(page*rpp+1)}
        if not unicodedLocation is None:
            q["l"]=unicodedLocation.encode("utf-8")
        url+="?"+urllib.urlencode(q)

        self._geoOnly=geoOnly
        self._url=url
        self.Sync()
        
def Search(unicodedQuery,num=500,geoOnly=True):
    def _search(q,n,p,g):
        if(n<=500):
            return SearchResult(q,n,p,g)
        else:
            res1=SearchResult(q,500,p,g)
            if res1.TotalCount>(p+1)*500:
                res2=_search(q,n-500,p+1,g)
                res1.Photos.extend(res2.Photos)
                del res2
            return res1
    return _search(unicodedQuery,num,0,geoOnly)

class PhotoSearch:
    '''
    #example.(crawling)
    from yi01lib.SearchEngine import Picasa
    
    f=Picasa.PhotoSearch()
    f.HasGeo=True
    results=f.Search(u"Kyoto",300)
    for p in results:
        print p.GetURL()
        print p.PhotoID,p.GetLatLng()
    '''
    
    def __init__(self):
        self.geoOnly=True
        self.Location=None
    
    def SetLocation(self,unicodedLocation):
        self.Location=unicodedLocation
        return self
    
    def Search(self,unicodedQuery,num=500):
        return self.__search(unicodedQuery,num,0)
    
    def __search(self,q,n,p):
        if n<500:
            return SearchResult(q,n,p,self.geoOnly,self.Location)
        else:
            res1=SearchResult(q,500,p,self.geoOnly,self.Location)
            if res1.TotalCount>(p+1)*500:
                res2=self.__search(q,n-500,p+1)
                res1.Photos.extend(res2.Photos)
                del res2
            return res1
